package org.xtframe.service.impl;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import javax.swing.ImageIcon;

import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jbpm.api.JbpmException;
import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.history.HistoryProcessInstance;
import org.jbpm.api.history.HistoryProcessInstanceQuery;
import org.jbpm.api.history.HistoryTask;
import org.jbpm.api.history.HistoryTaskQuery;
import org.jbpm.api.model.ActivityCoordinates;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.xtframe.entity.UserData;
import org.xtframe.service.AjaxDataHandler;
import org.xtframe.service.AjaxDataHandlerException;
import org.xtframe.util.CommonUtil;
import org.xtframe.util.ContextUtil;
import org.xtframe.util.JbpmUtil;
import org.xtframe.util.OsCacheUtil;

@Service
@Scope("prototype")
public class ProcessViewDataHandler implements AjaxDataHandler {

	private final Log logger = LogFactory.getLog(getClass());

	public Map<String, Object> execute(String strData) {
		Map<String, Object> map = new HashMap<String, Object>();
		
		try {
			UserData userData = ContextUtil.getCurrentUserData();
			if(userData == null){
				map.put(STATUS, false);
				map.put(LOGIN, true);
				throw new AjaxDataHandlerException("未登陆执行获取流程视图信息", 1);
			}
			
			JSONObject objJson = JSONObject.fromObject(strData);
			int iType = objJson.optInt("iType", -1);
			String id = objJson.optString("id", null);
			if(iType==-1 || id==null) throw new AjaxDataHandlerException("获取流程视图信息参数有误");
			
			Map<String, Object> data = new HashMap<String, Object>();
			//iType: 1表示流程定义Id，2表流程Id，3表示任务Id
			if(iType == 1){
				setImageInfo(id, data);
			} else if(iType == 2) {
				setNodeInfo(id, data);
			} else if(iType == 3){
				HistoryTaskQuery historyTaskQuery = JbpmUtil.getInstance().getHistoryService().createHistoryTaskQuery();
				historyTaskQuery.taskId(id);
				HistoryTask historyTask = historyTaskQuery.uniqueResult();
				setNodeInfo(historyTask.getExecutionId(), data);
			}
			map.put(STATUS, true);
			map.put(OBJECT, data);
			
		} catch(AjaxDataHandlerException ex){
			logger.warn(ex.toString());
			if(ex.getFlag() == 0){
				map.clear();
				map.put(STATUS, false);
			}
		} catch (Exception e) {
			logger.error(e.toString());
			map.clear();
			map.put(STATUS, false);
		}
		
		return map;
	}
	
	public static final String IMAGE_INFO_CACHE_KEY_PREFIX = "imageInfo_";// 图片信息缓存Key前缀
	private void setImageInfo(String processDefinitionId, Map<String, Object> data){
		String key = IMAGE_INFO_CACHE_KEY_PREFIX + processDefinitionId;
		
		@SuppressWarnings("unchecked")
		Map<String, Integer> imageInfo = (Map<String, Integer>)OsCacheUtil.getFromCache(key);
		if(imageInfo == null){
			imageInfo = new HashMap<String, Integer>(2);
			
			RepositoryService repositoryService = JbpmUtil.getInstance().getRepositoryService();
			ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
					.processDefinitionId(processDefinitionId).uniqueResult();
			InputStream inputStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), 
					processDefinition.getImageResourceName());
			byte imgdata[] = CommonUtil.InputStreamToByte(inputStream);
			ImageIcon img = new ImageIcon(imgdata);
			imageInfo.put("imgWidth", img.getIconWidth());
			imageInfo.put("imgHeight", img.getIconHeight());
			
			OsCacheUtil.putInCache(key, imageInfo);
		}
		
		data.put("imgWidth", imageInfo.get("imgWidth"));
		data.put("imgHeight", imageInfo.get("imgHeight"));
	}
	
	private void setNodeInfo(String processInstanceId, Map<String, Object> data){
		ProcessInstance processInstance = JbpmUtil.getInstance().getExecutionService()
				.findProcessInstanceById(processInstanceId);
		String activityName = null;
		String processDefinitionId = null;
		if(processInstance != null){
			processDefinitionId = processInstance.getProcessDefinitionId();
			activityName = processInstance.findActiveActivityNames().iterator().next();
		} else {
			HistoryProcessInstanceQuery histProcQuery = JbpmUtil.getInstance().getHistoryService().createHistoryProcessInstanceQuery();
			histProcQuery.processInstanceId(processInstanceId);
		    HistoryProcessInstance historyProcessInstance = histProcQuery.uniqueResult();
		    if (historyProcessInstance == null) 
		    	throw new JbpmException("出错，id=" + processInstanceId + "的流程实例不存在！");
			
		    processDefinitionId = historyProcessInstance.getProcessDefinitionId();
			activityName = historyProcessInstance.getEndActivityName();
		}
		
		setImageInfo(processDefinitionId, data);
		RepositoryService repositoryService = JbpmUtil.getInstance().getRepositoryService();
		ActivityCoordinates ac = repositoryService.getActivityCoordinates(
				processDefinitionId, activityName);
		data.put("x", ac.getX());
		data.put("y", ac.getY());
		data.put("width", ac.getWidth());
		data.put("height", ac.getHeight());
	}

}
